package plugin

import (
	"context"
	log "github.com/sirupsen/logrus"
	"reflect"
)

type PluginExecutor struct {
	exts   []*PluginDef
	isInit bool
}

func (e *PluginExecutor) Execute(ctx context.Context, pluginId string, in interface{}, fn func(pluginInterface interface{}) error) error {
	for _, ext := range e.getPlugins(pluginId) {
		pluginInterface := ext.Service
		if ce, ok := pluginInterface.(RuleChecker); ok {
			if !ce.Check(ctx, in) {
				continue
			}
		}
		log.Debug(pluginId, ": ", reflect.TypeOf(ext).String())
		err := fn(pluginInterface)
		if err != nil {
			return err
		}
	}
	return nil
}

func (e *PluginExecutor) getPlugins(pluginCode string) []*PluginDef {

	if e.isInit {
		return e.exts
	}
	defs, ok := Get(pluginCode)
	if !ok {
		return e.exts
	}
	e.exts = defs
	e.isInit = true
	log.Info("get by plugin code: ", pluginCode, " , ", defs)
	return e.exts
}
